package objetos;

import java.util.Observable;
import movimiento.Posicion;
import objetos.proyectiles.Proyectil;
import org.jdom.*;
import ar.uba.fi.algo3.titiritero.*;
import ar.uba.fi.algo3.titiritero.vista.Imagen;
import auxiliares.Vector;

/*
 * Clase que modela las caracteristicas b�sicas de los objetos m�viles.
 */
public abstract class ObjetoMovil extends Observable implements Posicionable {
	private int tamanio;
	private Energia energia;
	private Posicion posicion = null;
	private Vector velocidad;
	private boolean destruido;
	private String bando;
	/*
	 * Annotation agregada para que no moleste porque no se usa el atributo en
	 * esta clase
	 */
	@SuppressWarnings("unused")
	private int numeroSerie;
	private static int proximoNumeroSerie = 0;

	public ObjetoMovil() {
		this.numeroSerie = ++proximoNumeroSerie;
		this.destruido = false;
	}

	/*
	 * Modela el comportamiento de un objeto m�vil al colisionar con un
	 * proyectil
	 */
	public void colisionConProyectil(Proyectil bala) {
		bala.daniarObjetoMovil(this);
		bala.destruir();
	}

	public void recibirDanio(Danio danio) {
		this.energia.disminuirEnergia(danio.getCantidad());
		if (this.energia.getCantidad() <= 0) {
			this.destruir();
		}
	}

	public void recuperarEnergia(Energia cantidad) {
		this.energia.aumentarEnergia(cantidad.getCantidad());
	}

	public void destruir() {
		this.destruido = true;

		setChanged();
		notifyObservers();
	}

	public void darVida() {
		destruido = false;
	}

	public boolean esAliado() {
		return this.bando == "aliado";
	}

	public boolean esEnemigo() {
		return this.bando == "enemigo";
	}

	public boolean estaEnColisionCon(ObjetoMovil objeto) {
		if (objeto == null) {
			return false;
		}
		double distanciaCentros = this.posicion
				.distanciaA(objeto.getPosicion());
		double sumaTamanios = this.tamanio + objeto.getTamanio();
		return distanciaCentros <= sumaTamanios;
	}

	public void setDestruido(boolean estado) {
		this.destruido = estado;
	}

	public boolean estaDestruido() {
		return destruido;
	}

	public int getCantidadEnergia() {
		return energia.getCantidad();
	}

	public Energia getEnergia() {
		return energia;
	}

	public void setEnergia(Energia energia) {
		this.energia = energia;
	}

	public int getTamanio() {
		return tamanio;
	}

	public void setTamanio(int tamanio) {
		this.tamanio = tamanio;
	}

	public Posicion getPosicion() {
		return posicion;
	}

	public void setPosicion(Posicion posicion) {
		this.posicion = posicion;
	}

	public Vector getVelocidad() {
		return velocidad;
	}

	public void setVelocidad(Vector velocidad) {
		this.velocidad = velocidad;
	}

	public String getBando() {
		return bando;
	}

	public void setBando(String bando) {
		this.bando = bando;
	}

	/* Persistencia */

	/* Constructor a partir de nodoXML */
	public ObjetoMovil(Element nodo) {
		this.setBando(nodo.getAttributeValue("bando"));
	}

	/* NodoXML a partir de instancia */
	public Element obtenerNodo() {
		Element nodo = new Element("ObjetoMovil");
		nodo.setAttribute(new Attribute("bando", this.getBando().toString()));
		return nodo;
	}

	/*
	 * M�todo que devuelve una vista para el objeto m�vil. Requiere que haya una
	 * clase FactoryVistas declarada
	 */
	public abstract Imagen darVista(ControladorJuego controlador);

	/* Solo se usan para dibujar al objeto, no es la posicion real */
	@Override
	public int getX() {
		return this.getPosicion().getEnX() - this.tamanio;
	}

	@Override
	public int getY() {
		return this.getPosicion().getEnY() - this.tamanio;
	}

}
